#!/usr/bin/env python
#
# Copyright (C) 2005-2020 ABINIT Group (Yann Pouillon)
#
# This file is part of the ABINIT software package. For license information,
# please see the COPYING file in the top-level directory of the ABINIT source
# distribution.
#
from __future__ import print_function, division, absolute_import #, unicode_literals

try:
    from ConfigParser import ConfigParser
except ImportError:
    from configparser import ConfigParser
from time import gmtime,strftime

import os
import re
import sys

class MyConfigParser(ConfigParser):

  def optionxform(self,option):
    return str(option)

# ---------------------------------------------------------------------------- #

#
# Subroutines
#

# Top Makefile
def makefile_top(name,stamp):

  return """#
# Makefile for ABINIT                                      -*- Automake -*-
#

# Generated by %s on %s

#
# IMPORTANT NOTE
#
# Any manual change to this file will systematically be overwritten.
# Please modify the %s script or its config file instead.
#

# Utilities for nightly builds
if DO_BUILD_TIMEOUT
  SUBDIRS = Timeout
endif

# minimun test for checking testsuite machinery
check-local:
	[ -f "runtests.py" ] && ./runtests.py fast -o1 --no-colors --no-logo || $(top_srcdir)/runtests.py fast -o1 --no-colors --no-logo --with-pickle=0
	@rm -rf Test_suite .prev_run.pickle

# Display help by default
all-local: help

if DO_BUILD_TIMEOUT
timeout-stamp:
	cd Timeout && $(MAKE) @SET_MAKE@
	touch timeout-stamp
else
timeout-stamp:
	@echo "Timeout is disabled"
	touch timeout-stamp
endif

help:
	@cat $(top_srcdir)/doc/help_make/help_make_tests

""" % (name,stamp,name)

# Makefile for timeout
def makefile_timeout(name,stamp):

  return """#
# Makefile for ABINIT                                      -*- Automake -*-
#

# Generated by %s on %s

#
# IMPORTANT NOTE
#
# Any manual change to this file will systematically be overwritten.
# Please modify the %s script or its config file instead.
#

bin_PROGRAMS = timeout

timeout_SOURCES = timeout.c

EXTRA_DIST = \
	_Timeout_
""" % (name,stamp,name)

# File lists
def file_list(name,my_dir,my_files=[]):
  tmp = "# Files from %s\n%s =" % (my_dir,name)
  olddir = re.compile(",.*")
  pycomp = re.compile("\.pyc$")
  tmpdir = re.compile("/tmp-.*")
  vimswp = re.compile("\..*\.swp")

  # Find files to install
  for root,dirs,files in os.walk(my_dir):
    # Clean-up lists
    if ( "Makefile.am" in files ):
      files.remove("Makefile.am")
    if ( "Makefile.in" in files ):
      files.remove("Makefile.in")
    if ( "Makefile" in files ):
      files.remove("Makefile")

    # Sort lists
    dirs.sort()
    files.sort()

    # We don't want to distribute nor install temporary directories
    if ( (not olddir.search(root)) and (not tmpdir.search(root)) ):

      # Add data files
      for dat in files:
        if ( (not vimswp.match(dat)) and (not pycomp.search(dat)) ):
          tmp += " \\\n\t%s" % (os.path.join(root,dat))

  # Add possible extra files
  for item in my_files:
    tmp += " \\\n\t%s" % (os.path.join(my_dir,item))

  tmp += "\n\n"

  return tmp



# ---------------------------------------------------------------------------- #

#
# Main program
#

# Initial setup
my_name    = "make-makefiles-tests"
my_configs = ["config/specs/tests.conf"]
my_output  = "Makefile.am"

# Check if we are in the top of the ABINIT source tree
if ( not os.path.exists("configure.ac") or
     not os.path.exists("config/specs/tests.conf") ):
  print("%s: You must be in the top of the ABINIT Test Suite source tree." % my_name)
  print("%s: Aborting now." % my_name)
  sys.exit(1)

# Read config file(s)
cnf = MyConfigParser()
for cnf_file in my_configs:
  if ( not os.path.exists(cnf_file) ):
    print("%s: Could not find config file (%s)." % (my_name,cnf_file))
    print("%s: Aborting now." % my_name)
    sys.exit(2)

# What time is it?
now = strftime("%Y/%m/%d %H:%M:%S +0000",gmtime())

# Init
cnf.read(my_configs[0])
abinit_tests = cnf.sections()
abinit_tests.sort()

# Start to write Makefile.am
mf = open(my_output, "wt")
mf.write(makefile_top(my_name,now))

# Prepare EXTRA_DIST target
ins = "nobase_dist_pkgdata_DATA = \\\n\t$(top_level_files) \\\n\t$(tests_scripts)" + \
  " \\\n\t$(psps_for_tests) \\\n\t$(doc_files) \\\n\t$(tests_in_inps) \\\n\t$(pymods)"

# Prepare clean-local target
cln = "clean-local:\n\trm -f timeout-stamp\n\trm -rf built-in/tmp-*\n"

# Write file lists and targets

# Add Files in the top level directory (*.py and *.rst)
import glob
top_level_files = glob.glob('*.py') + glob.glob('*.rst')

string = "# Files from %s\n%s =" % ("top_level_dir","top_level_files")
for fname in top_level_files:          
   string += " \\\n\t%s" % fname
string += "\n\n"
mf.write(string)

mf.write(file_list("tests_scripts","Scripts"))
mf.write(file_list("psps_for_tests","Psps_for_tests"))
mf.write(file_list("doc_files","doc"))
mf.write(file_list("tests_in_inps","built-in"))
mf.write(file_list("pymods","pymods"))

for series in abinit_tests:

  # Init
  aliases = cnf.get(series,"aliases")
  dir_ext = cnf.get(series,"external")
  dir_mpi = cnf.get(series,"mpi")
  dir_opt = cnf.get(series,"optional")
  if ( cnf.has_option(series,"extra_files") ):
    dir_add = cnf.get(series,"extra_files").split()
  else:
    dir_add = []

  # Append info
  ins += " \\\n\t$(tests_%s_inps)" % (series)
  cln += "\trm -rf %s/tmp-*\n" % (series)

  # Write file list
  mf.write(file_list("tests_%s_inps" % (series),series,dir_add))

cln += "\n"
mf.write(ins + "\n\n" + cln)

# Look for additional information
add = "config/makefiles/tests.am"
if ( os.path.exists(add) ):
  mf.write(open(add, "rt").read())

mf.close()

# Write down timeout Makefile
open("Timeout/Makefile.am", "wt").write(makefile_timeout(my_name,now))
